package com.easyJava.builder;

import com.easyJava.bean.Constants;
import com.easyJava.bean.FieldInfo;
import com.easyJava.bean.TableInfo;
import com.easyJava.utils.DateUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 *  1. 有一个小问题，就是在生成po文件的时候，如果有is_xxx , 并且是Boolean 类型 , set get 方法会有问题
 * 这是一个用来生成po文件的类
 */
public class BuildQuery {

    private static final Logger logger = LoggerFactory.getLogger(BuildQuery.class);
    private static final String BIGDECIMAL_PACKAGE  = "import java.math.BigDecimal;";
    private static final String DATA_PACKAGE = "import java.util.Date;";
    /**
     * 生成po文件
     * @param tableInfo
     */
    public static void execute(TableInfo tableInfo){
        File folder = new File(Constants.PATH_QUERY);
        if(!folder.exists()){
            folder.mkdirs();
        }
        File file_Query = new File(folder,tableInfo.getBeanName()+Constants.QUERY_NAME +".java");
        OutputStream outputStream =null;
        OutputStreamWriter outputStreamWriter = null;
        BufferedWriter bufferedWriter = null;

        try{
            outputStream = new FileOutputStream(file_Query);
            outputStreamWriter = new OutputStreamWriter(outputStream,"utf-8");
            bufferedWriter = new BufferedWriter(outputStreamWriter);
            //包名
            bufferedWriter.write("package " + Constants.PACKAGE_QUERY + ";" );
            bufferedWriter.newLine();
            //判断是否有Double类型
            if(tableInfo.getHaveBigDecimal()){
                bufferedWriter.write(BIGDECIMAL_PACKAGE);
                bufferedWriter.newLine();
                bufferedWriter.newLine();
            }
            //判断是否有时间类型
            DealWithDate(bufferedWriter,tableInfo);

            BuildComment.ClassComment(bufferedWriter,tableInfo);
            bufferedWriter.newLine();
            bufferedWriter.write("public class " + tableInfo.getBeanName() + Constants.QUERY_NAME+ "{");
            bufferedWriter.newLine();

            //处理所有字段
            List<FieldInfo>AllFieldInfo = new ArrayList<>(tableInfo.getFieldInfoList());
            AllFieldInfo.addAll(tableInfo.getExtendFieldInfoList());
            //处理字段
            for(FieldInfo fieldInfo :AllFieldInfo){
                //字段注释
                BuildComment.FieldComment(bufferedWriter,fieldInfo);
                //字段
                bufferedWriter.write("\t"+Constants.PRIVATE + " " + fieldInfo.getJavaType() +" " + fieldInfo.getPropertyName() + ";");
                bufferedWriter.newLine();
                bufferedWriter.newLine();
                //处理set,get方法
            }
            for(FieldInfo fieldInfo :AllFieldInfo){
                //处理set,get方法
                doMethod(bufferedWriter,fieldInfo.getJavaType(),fieldInfo.getPropertyName());
                bufferedWriter.newLine();
            }
            bufferedWriter.write("}");
            bufferedWriter.flush();
        }catch (Exception e){
            logger.error("生成po文件失败",e);
        }finally {
            try {
                bufferedWriter.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            try {
                outputStreamWriter.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            try {
                outputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**  TODO: 可以 improve
     * 处理Date类型 的Query问题  TODO：有异常的方法怎么样处理
     * @param bufferedWriter
     * @param fieldInfo
     */
    public static void DealWithDateType(BufferedWriter bufferedWriter ,FieldInfo fieldInfo) throws IOException {
        String properStart = Constants.query_date_start + fieldInfo.getPropertyName() ;
        bufferedWriter.write("\t"+Constants.PRIVATE + " " + Constants.STRING_TYPE+ " " + properStart + ";");
        bufferedWriter.newLine();
        bufferedWriter.newLine();
        doMethod(bufferedWriter,Constants.STRING_TYPE,properStart);
        bufferedWriter.newLine();

        String properEnd = fieldInfo.getPropertyName() + Constants.query_date_end;
        bufferedWriter.write("\t"+Constants.PRIVATE + " " + Constants.STRING_TYPE+ " " + properEnd + ";");
        bufferedWriter.newLine();
        bufferedWriter.newLine();
        doMethod(bufferedWriter,Constants.STRING_TYPE,properEnd);
        bufferedWriter.newLine();
    }

    /**
     * 处理Date类型
     * @param bufferedWriter
     * @param tableInfo
     */
    public static void DealWithDate(BufferedWriter bufferedWriter ,TableInfo tableInfo) throws IOException {
        if(tableInfo.getHaveDate() || tableInfo.getHaveDateTime()){
            bufferedWriter.write(DATA_PACKAGE);
            bufferedWriter.newLine();
        }
    }
    /**
     * 生成set,get方法
     * @param bw
     * @param JavaType
     * @param PropertyName
     */
    public static void doMethod(BufferedWriter bw ,String JavaType,String PropertyName) throws IOException {

        bw.write("\t" + Constants.PUBLIC + " " + JavaType + " get" + PropertyName.substring(0,1).toUpperCase() + PropertyName.substring(1) + "(){");
        bw.newLine();
        bw.write("\t\t return " + PropertyName + ";");
        bw.newLine();
        bw.write("\t}");
        bw.newLine();
        bw.write("\t" + Constants.PUBLIC + " " + "void" + " set" + PropertyName.substring(0,1).toUpperCase()
                + PropertyName.substring(1) + "("+JavaType+ " "+ PropertyName + " ){");
        bw.newLine();
        bw.write("\t\t this." + PropertyName + "=" + PropertyName + ";");
        bw.newLine();
        bw.write("\t}");
        bw.newLine();
    }

}
